

class StrImgCode {
    constructor(props) {
        this.config = this.objectAssign(props);
        this.canvas = null;
        this.code = '';
    }

    // 创建
    create = _ => {
        // canvas 不存在时创建canvas
        if(!this.canvas){
            this.canvas = document.createElement("canvas");
            this.canvas.id = 'StrImgCode';
            this.canvas.width = this.config.width;
            this.canvas.height = this.config.height;
        }

        // 判定 canvas 兼容性
        if(!this.canvas.getContext) {
            console.error('您的浏览器版本不支持canvas！');
            return {
                imgUrl : '',
                code : 500,
                message : '您的浏览器版本不支持canvas！',
                imgCode : '',
            };
        }
        let ctx = this.canvas.getContext('2d');
        ctx.textBaseline = "middle";
        ctx.fillStyle = this.randomColor(180, 240);
        ctx.fillRect(0, 0, this.config.width, this.config.height);

        // 判断验证码类型
        let txtArr;
        if(this.config.type === "blend") {
           txtArr = this.numArr.concat(this.strArr);
        } else if(this.config.type === "number") {
            txtArr = this.numArr;
        } else {
            txtArr = this.strArr;
        }
        // 创建字符
        for(let i = 1; i <= this.config.length; i++) {
            let txt = txtArr[this.randomNum(0, txtArr.length)];
            this.code += txt;
            ctx.font = this.randomNum(this.config.height/2, this.config.height) + 'px SimHei'; // 随机生成字体大小
            ctx.fillStyle = this.randomColor(50, 160); // 随机生成字体颜色
            ctx.shadowOffsetX = this.randomNum(-3, 3);
            ctx.shadowOffsetY = this.randomNum(-3, 3);
            ctx.shadowBlur = this.randomNum(-3, 3);
            ctx.shadowColor = "rgba(0, 0, 0, 0.3)";
            let x = this.config.width / ( this.config.length + 1) * i;
            let y = this.config.height / 2;
            let deg = this.randomNum(-30, 30);
            /** 设置旋转角度和坐标原点* */
            ctx.translate(x, y);
            ctx.rotate(deg * Math.PI / 180);
            ctx.fillText(txt, 0, 0);
            /** 恢复旋转角度和坐标原点* */
            ctx.rotate(-deg * Math.PI / 180);
            ctx.translate(-x, -y);
        }

        // 创建干扰线
        for(let i = 0; i < 3; i++) {
            ctx.strokeStyle = this.randomColor(40, 180);
            ctx.beginPath();
            ctx.moveTo(this.randomNum(0, this.config.width), this.randomNum(0, this.config.height));
            ctx.lineTo(this.randomNum(0, this.config.width), this.randomNum(0, this.config.height));
            ctx.stroke();
        }

        // 创建干扰点
        for(let i = 0; i < this.config.width / 3; i++) {
            ctx.fillStyle = this.randomColor(0, 255);
            ctx.beginPath();
            ctx.arc(this.randomNum(0, this.config.width), this.randomNum(0, this.config.height), 1, 0, 2 * Math.PI);
            ctx.fill();
        }
        // 生成base64
        return {
            imgUrl : this.canvas.toDataURL('image/jpg'),
            code : 200,
            message : '创建成功！',
            imgCode : this.code,
        };
    };

    // 获取
    getCode = _ => {
        return this.code;
    };

    // 刷新
    refresh = _ => {
        // 重置 code
        this.code = '';
        // 创建验证码
        return this.create();
    };

    // 验证
    submit = value => {
        let {code} = this;
        let {matchCase} = this.config;
        if(matchCase){
            // 区分大小写
            return code === value;
        }
        // 不区分大小写
        return code.toLowerCase() === value.toLowerCase();
    };
}

// TODO 生成随机色
StrImgCode.prototype.randomColor = (min, max) => {
    let r = StrImgCode.prototype.randomNum(min, max);
    let g = StrImgCode.prototype.randomNum(min, max);
    let b = StrImgCode.prototype.randomNum(min, max);
    return "rgb(" + r + "," + g + "," + b + ")";
};

// TODO 生成随机数
StrImgCode.prototype.randomNum = (min, max) => {
    return Math.floor(Math.random() * (max - min) + min);
};

// TODO 生成随机字母
StrImgCode.prototype.getAllLetter = () => {
    let letterStr = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z";
    return letterStr.split(",");
};

// TODO 生成随机数字
StrImgCode.prototype.getAllNumber = () => {
    return "1,2,3,4,5,6,7,8,9".split(",");
};

// TODO 设置数字
StrImgCode.prototype.numArr = StrImgCode.prototype.getAllNumber();

// TODO 设置字母
StrImgCode.prototype.strArr = StrImgCode.prototype.getAllLetter();

// TODO 合并配置
StrImgCode.prototype.objectAssign = (props) => {
    if(!props || typeof props !== 'object'){
        props = {}
    }
    let config = {
        type : 'blend', // 图形验证码默认类型blend:数字字母混合类型、number:纯数字、letter:纯字母
        width : 100, // 图片宽度
        height : 50, // 图片高度
        length : 4, // 验证码位数（需要足够宽否则会很挤）
        matchCase : false, // 是否区分大小写
    };
    return Object.assign(config, props)
};

module.exports = StrImgCode;
